from faker import Faker
import random
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from data_mock.utils import FileUtil
from data_mock.utils import MysqlUtils_AI
fake = Faker('zh_CN')

# ========== 药品数据配置 ==========
ANTI_CANCER_DRUGS = [
    {
        'generic_name': '紫杉醇',
        'trade_names': ['泰素', '紫素', '安素泰'],
        'manufacs': ['百时美施贵宝', '恒瑞医药', '齐鲁制药'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['注射液', '脂质体'],
        'specs': ['30mg/5ml', '100mg/16.7ml'],
        'packing': ['1支/盒', '5支/盒']
    },
    {
        'generic_name': '顺铂',
        'trade_names': ['顺铂注射液', '诺欣'],
        'manufacs': ['齐鲁制药', '豪森药业'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['注射液'],
        'specs': ['10mg/支', '20mg/支'],
        'packing': ['1支/盒', '10支/盒']
    },
    {
        'generic_name': '卡铂',
        'trade_names': ['波贝', '卡铂注射液'],
        'manufacs': ['恒瑞医药', '正大天晴'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['注射液'],
        'specs': ['100mg/10ml'],
        'packing': ['1支/盒']
    },
    {
        'generic_name': '奥沙利铂',
        'trade_names': ['乐沙定', '艾恒'],
        'manufacs': ['赛诺菲', '恒瑞医药'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['注射液'],
        'specs': ['50mg/支', '100mg/支'],
        'packing': ['1支/盒', '5支/盒']
    },
    {
        'generic_name': '多西他赛',
        'trade_names': ['泰索帝', '多帕菲'],
        'manufacs': ['赛诺菲', '恒瑞医药'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['注射液'],
        'specs': ['20mg/支', '80mg/支'],
        'packing': ['1支/盒']
    },
    {
        'generic_name': '吉西他滨',
        'trade_names': ['健择', '泽菲'],
        'manufacs': ['礼来', '恒瑞医药'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['冻干粉针'],
        'specs': ['200mg/支', '1g/支'],
        'packing': ['1支/盒']
    },
    {
        'generic_name': '培美曲塞',
        'trade_names': ['力比泰', '普来乐'],
        'manufacs': ['礼来', '豪森药业'],
        'approval_no': '国药准字H{}'.format(random.randint(1000000, 9999999)),
        'forms': ['冻干粉针'],
        'specs': ['100mg/支', '500mg/支'],
        'packing': ['1支/盒']
    }
]

INSURANCE_TYPES = ['甲类医保', '乙类医保', '自费', '特殊药品']
HOSPITAL_DRUG_CODE_PREFIX = 'DRG'


# ========== 批次时间配置 ==========
def generate_DAY_RANGE(start_day, end_day):
    """

    :param start_day:  必须是 YYYY-MM-DD 这种格式
    :param end_day:
    :return:
    """
    # 字符串转datetime类型的
    start = datetime.strptime(start_day, "%Y-%m-%d")
    end = datetime.strptime(end_day, "%Y-%m-%d")
    days = []

    current = start
    while current <= end:
        # print("当前:", current, "结束:", end, "比较结果:", current <= end)
        days.append(current.strftime("%Y-%m-%d"))
        # 把一个 datetime 对象 格式化成 字符串。
        # strftime 的意思是：string format time（把时间格式化成字符串）
        current += relativedelta(days=1)  # 每次加一个月，循环推进

    return days


# 配置月份范围（可修改）
DAY_RANGE = generate_DAY_RANGE("2025-08-01", "2025-08-03")  # 多少个月


def generate_records_per_day(day: str):
    """
    :param day: '2025-08-01'
    :return:
    """
    # datetime返回的 day和 day是 int类型，没有前导 0（比如 8而不是 08）。
    # 如果需要 08这样的格式，可以用 f"{day:02d}"格式化：
    try:
        date_obj = datetime.strptime(day, '%Y-%m-%d')
        return 10 if date_obj.day % 2 == 0 else 5
    except ValueError as e:
        raise ValueError(f'无效的日期格式{day},应该为YYYY-MM-DD')

    # ========== 核心生成函数 ==========


def generate_drug_purchase_records():
    """生成抗肿瘤药物采购记录"""
    sql_statements = []
    record_count = 0

    for day in DAY_RANGE:  # 1个月
        RECORDS_PER_day = generate_records_per_day(day)
        for i in range(1, RECORDS_PER_day + 1):
            if record_count >= 200:
                break
            record_count += 1
            # 开始赋值
            drug = random.choice(ANTI_CANCER_DRUGS)
            trade_name = random.choice(drug['trade_names'])
            manufac = random.choice(drug['manufacs'])
            form = random.choice(drug['forms'])
            spec = random.choice(drug['specs'])
            packing = random.choice(drug['packing'])

            # 生成药品价格（基于规格）
            base_price = {
                '紫杉醇': 800,
                '顺铂': 50,
                '卡铂': 200,
                '奥沙利铂': 600,
                '多西他赛': 1000,
                '吉西他滨': 300,
                '培美曲塞': 1500
            }.get(drug['generic_name'], 500)

            # 根据规格调整价格
            if '100mg' in spec:
                price = base_price * 2
            elif '50mg' in spec:
                price = base_price * 1.5
            else:
                price = base_price

            price = round(price * random.uniform(0.8, 1.2), 2)

            # 生成采购数据
            pur_quantity = random.randint(10, 100)
            pur_total_price = round(price * pur_quantity, 2)

            # 最后整合成一个json
            data = {
                'pur_sn': f"PUR{day}{i:03d}",
                'hos_drug_code': f"{HOSPITAL_DRUG_CODE_PREFIX}{random.randint(1000, 9999)}",
                'generic_name': drug['generic_name'],
                'trade_name': trade_name,
                'manufac': manufac,
                'approval_no': drug['approval_no'],
                'form': form,
                'spec': spec,
                'packing_quantity': packing.split('/')[0],
                'packing_unit': packing.split('/')[1],
                'pur_unit_price': price,
                'pur_quantity': pur_quantity,
                'pur_total_price': pur_total_price,
                'pur_date': fake.date_time_between(
                    start_date=datetime.strptime(day, "%Y-%m-%d"),
                    end_date=(datetime.strptime(day, "%Y-%m-%d") + relativedelta(days=1))
                ).strftime('%Y-%m-%d %H:%M:%S'),
                'insurance_type': random.choice(INSURANCE_TYPES),
                'extend_data1': f"批号：{random.randint(100000, 999999)}",
                'extend_data2': f"有效期至：{(datetime.now() + timedelta(days=random.randint(180, 720))).strftime('%Y-%m-%d')}",
                'yy_upload_status': 0,
                'yy_etl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'yy_upload_time': None,
                'yy_batch_time': day,
                'yy_record_batch_id': f"BATCH{day}_{i}",
                'yy_backfill_time': None,
                'yy_backfill_status': None
            }
            # 数据值传过去生产sql
            sql = _generate_sql('b01_1', data)
            print(sql)
            sql_statements.append(sql)
            """"
            INSERT INTO `b01_1` (`pur_sn`, `hos_drug_code`, `generic_name`, `trade_name`, `manufac`, `approval_no`, `form`, `spec`, `packing_quantity`, `packing_unit`, `pur_unit_price`, `pur_quantity`, `pur_total_price`, `pur_date`, `insurance_type`, 
            `extend_data1`, `extend_data2`, `yy_upload_status`, `yy_etl_time`, 
            `yy_upload_time`, `yy_batch_time`, `yy_record_batch_id`, `yy_backfill_time`, 
            `yy_backfill_status`) VALUES ('PUR202508015', 'DRG1977', '顺铂', '诺欣', '豪森药业', '国药准字H8106408', '注射液', '10mg/支', '1支', '盒', 56.44, 94, 5305.36, '2025-08-09 17:36:11', '乙类医保', '批号：223573', '有效期至：2027-03-27', 0, '2025-10-03 19:55:34', NULL, '202508', 'BATCH202508_15', NULL, NULL);
            """

    return sql_statements


def _generate_sql(table, data):
    """
    传入表和data
    :param table:
    :param data:
    :return:
    字典值
    """
    """生成SQL插入语句"""
    columns = ', '.join([f'`{k}`' for k in data.keys()])
    # print('--------',type(columns))  str类型的
    # `patient_id`, `visit_sn`, `name`
    values = []
    for v in data.values():
        if v is None:
            values.append('NULL')  # 如果值是 None（Python 里的空值），SQL 里要用 NULL 表示，不能写 'None'。
        elif isinstance(v, (int, float)):
            values.append(str(v))
            print('------------', type(str(v))
                  )
        else:
            escaped_value = str(v).replace("'", "''")
            values.append(f"'{escaped_value}'")

    return f"INSERT INTO `{table}` ({columns}) VALUES ({', '.join(values)})"


# ========== 执行生成 ==========
if __name__ == "__main__":
    print("开始生成抗肿瘤药物采购记录(b01_1表)...")
    print(f"月份范围：{DAY_RANGE[0]} 至 {DAY_RANGE[-1]}")

    records = generate_drug_purchase_records()

    print(type(records))

    # 生成的记录直接写入数据库
    MysqlUtils_AI.insert_data_to_hub(records,'b01-1')
    # FileUtil.generate_sql_file(records, "b01_1_drug_purchases.sql")
